package controllers;

import java.io.File;
import java.util.*;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.XML;
import org.json.JSONArray;

import play.*;
import play.mvc.*;
import play.db.jpa.*;

import java.util.*;

import javax.persistence.Query;

import models.*;
import contexlib.readFile;

public class Application extends Controller {

    public static void index() {
    	String contexStr = readFile.readFromFile("/home/michael/ec2basecluster.xml");
    	try{
    	    JSONObject json = XML.toJSONObject(contexStr);
    	    Contex contex = new Contex(json.toString());
            contex.save();
            renderJSON("ok");
    	}catch(JSONException e){
    		e.printStackTrace();
    	}
    }

    
    public static void initAction(Long contexid,Integer vmid,String ip,String hostname){
    	Contex contexObj = Contex.getcontex(contexid);
        String contexStr = contexObj.contexStr;
        JSONObject response = new JSONObject();
        boolean flag = true;
        String message = null;
        try{        
        	JSONObject json = new JSONObject(contexStr);
            int vmNumber = json.getJSONObject("cluster").getJSONArray("workspace").length();
            JSONArray vms = json.getJSONObject("cluster").getJSONArray("workspace");
            JSONObject vm = null;
            for (int i=0;i<vmNumber;i++){
                if(vmid.intValue() == vms.getJSONObject(i).getInt("vmid")){
                    vm = vms.getJSONObject(i);
                    break;
                }
            }

            if(vm == null){
            	message = "Can not find the information in the contex";
            	flag = false;
            	response.put("flag",flag);
            	response.put("message",message);
            	renderJSON(response.toString());
            }
        }catch(JSONException e){
        	e.printStackTrace();
        }
    }

    
    public static void query(Long contexid,Integer vmid) {
    	Contex contexObj = Contex.getcontex(contexid);
        String contexStr = contexObj.contexStr;
//        renderJSON(contexStr);
        try{
            boolean flag=false;
            String message=null;
            JSONObject response = new JSONObject();
            JSONObject json = new JSONObject(contexStr);
            int vmNumber = json.getJSONObject("cluster").getJSONArray("workspace").length();
            JSONArray vms = json.getJSONObject("cluster").getJSONArray("workspace");
            JSONObject vm = null;
            for (int i=0;i<vmNumber;i++){
                if(vmid.intValue() == vms.getJSONObject(i).getInt("vmid")){
                    vm = vms.getJSONObject(i);
                    break;
                }
            }

            if(vm == null){
            	message="No such vm with vmid " + vmid.toString();
            }else if(!vm.has("ctx")){
                message="No ctx for vm " + vmid.toString();
            }else if(!vm.getJSONObject("ctx").has("requires")){
                message="No requires section for vm " + vmid.toString();
            }else{
                JSONObject requires = vm.getJSONObject("ctx").getJSONObject("requires");

                //for identity
                if(requires.has("identity")){
                    JSONArray idens = new JSONArray();
                    for (int i=0;i<vmNumber;i++){
                        JSONArray nics = vms.getJSONObject(i).getJSONArray("nic");
                        if(nics.getJSONObject(0).has("ip")&&nics.getJSONObject(0).has("hostname")&&nics.getJSONObject(1).has("ip")&&nics.getJSONObject(1).has("hostname")){
                            idens.put(nics);
                        }else{
                            message="IP or HOSTNAME IS NOT AVAILABLE WHEN DEAL WITH IDENTITIES!";
                            response.put("flag", flag);
                            response.put("message", message);
                            renderJSON(response.toString());    
                        } 
                    }                    
                    response.put("identity",idens);                         
                }


                //for roles
                if(requires.has("role")){
//                	System.out.println("haha");
                    JSONObject rolesInfo = new JSONObject();
                    JSONArray roles = null;
                    if(requires.get("role") instanceof JSONArray){
                        roles = requires.getJSONArray("role"); 
                    }else{                   	
                        roles = new JSONArray();
                        roles.put(requires.getJSONObject("role"));
                    }
                        	
                    for(int j=0;j<roles.length();j++){
                        JSONArray roleArray = new JSONArray();
                        JSONObject reqRole = roles.getJSONObject(j);
                        String[] attributeKeys = JSONObject.getNames(reqRole);
                        ArrayList<String> attributes = new ArrayList<String>();
                        if(attributeKeys.length==1){
                        	attributes.add("ip");
                        	attributes.add("hostname");                     			
                        }else{
                        	for(String e: attributeKeys){
                        		if(!e.equals("name")) attributes.add(e);
                        	}
                        }
                        
                        
                        
                        for(int i=0;i<vmNumber;i++){
                        	if(!vms.getJSONObject(i).has("ctx"))continue;
                        	if(!vms.getJSONObject(i).getJSONObject("ctx").has("provides"))continue;
                        	else if(!vms.getJSONObject(i).getJSONObject("ctx").getJSONObject("provides").has("role")) continue;
                        	else{
                        		
                        		JSONObject proRole = null;
                        		if((vms.getJSONObject(i).getJSONObject("ctx").getJSONObject("provides").get("role") instanceof JSONObject)&&(vms.getJSONObject(i).getJSONObject("ctx").getJSONObject("provides").getJSONObject("role").getString("name").equals(reqRole.getString("name")))){
                        			proRole = vms.getJSONObject(i).getJSONObject("ctx").getJSONObject("provides").getJSONObject("role");
                        		}else if(vms.getJSONObject(i).getJSONObject("ctx").getJSONObject("provides").get("role") instanceof JSONArray){
                        			JSONArray proRoleArray = vms.getJSONObject(i).getJSONObject("ctx").getJSONObject("provides").getJSONArray("role");
                        			System.out.println(proRoleArray.toString());
                        			for(int p=0;p<proRoleArray.length();p++){
                        				if(proRoleArray.getJSONObject(p).getString("name").equals(reqRole.getString("name"))){
                        					proRole = proRoleArray.getJSONObject(p);
                        					break;
                        				}
                        			}
                        		}
                        		if(proRole==null) continue;
                        		else{
                        			JSONArray nics = vms.getJSONObject(i).getJSONArray("nic");
                        			JSONArray nicsInfo = new JSONArray();
                        			if(proRole.has("_interface")){
                        				JSONObject nicInfo = new JSONObject();
                        				String proNic = proRole.getString("_interface");
                        				for(int q=0;q<nics.length();q++){
                        	     		    if(nics.getJSONObject(q).getString("_interface").equals(proNic)){                       						    	
                        				        for(String e: attributes){
                        						    if(nics.getJSONObject(q).has(e)) nicInfo.put(e,nics.getJSONObject(q).getString(e));
                        						    else{
                        						    	message = e + "is not available when deal with role!";
                        						    	response.put("flag", flag);
                        						    	response.put("message", message);
                        						    	renderJSON(response.toString());
                        						    }
                        						}
                        						nicsInfo.put(nicInfo);
                        						break;
                        				    }                       							
                        				}              						
                        			}else{
                        				for(int q=0;q<nics.length();q++){
                        					JSONObject nicInfo = new JSONObject();
                        					for(String e: attributes){
                    						    if(nics.getJSONObject(q).has(e)) nicInfo.put(e,nics.getJSONObject(q).getString(e));
                    						    else{
                    						    	message = e + "is not available now!";
                    						    	response.put("flag", flag);
                    						    	response.put("message", message);
                    						    	renderJSON(response.toString());
                    						    }
                    						}
                        					nicsInfo.put(nicInfo);
                        				}                       				
                        			}
                        			if(nicsInfo.length()!=0) roleArray.put(nicsInfo);    	
                        			else{
                        				message = "NO SUCH A NIC WHEN DEAL WITH ROLE!";
        						    	response.put("flag", flag);
        						    	response.put("message", message);
        						    	renderJSON(response.toString());
                        			}
                        		}
                        				
                        	}                       				                        			                        					                        				                        			                       				                                         				
                        }
                        if(roleArray.length()!=0)
                            rolesInfo.put(reqRole.getString("name"),roleArray);
                        else{
                        	message = "Can not find this role anyway!";
					    	response.put("flag", flag);
					    	response.put("message", message);
					    	renderJSON(response.toString());
                        }
                    }                    
                    response.put("role", rolesInfo);                   
                }                                        
            } 
            
            
            flag=true;
            response.put("flag", flag);
            renderJSON(response.toString());
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
